package com.example.flowable.controller;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.example.annotations.*;
import com.example.auth.model.UserModel;
import com.example.auth.service.UserModelService;
import com.example.db.TableService;
import com.example.db.model.IPage;
import com.example.flowable.FLowableUtils;
import com.example.flowable.model.FlowableModel;
import com.example.flowable.model.ProcessModel;
import com.example.flowable.model.TableModel;
import com.example.flowable.model.TaskModel;
import com.example.flowable.service.FlowableModelService;
import com.example.flowable.service.FlowableService;
import com.example.flowable.service.TableModelService;
import com.example.utils.Results;
import com.example.utils.StringUtils;
import liquibase.pro.packaged.O;
import liquibase.pro.packaged.S;
import org.flowable.bpmn.model.*;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceBuilder;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;

import java.util.*;

/**
 * @Classname FlowableController
 * @Description TODO
 * @Date 2022/8/14 20:46
 * @Created by XiongXiong
 * @Author: X.I.O
 */
@Auth
@RestController("/flow")
public class FlowableController {

    @Autowired
    UserModelService userModelService;

    @Autowired
    FlowableModelService flowableModelService;

    @Autowired
    private TableModelService tableModelService;

    @Autowired
    FLowableUtils fLowableUtils;

    @Autowired
    private FlowableService flowableService;




    @PostMapping(value = "/getstartprocess",desc = "获取可新建的流程类型")
    public JSONObject getStartProcess(){
        List<FlowableModel> flowableModelList=flowableModelService.getFlowableModelList();
        return Results.success(flowableModelList);
    }

    @PostMapping(value = "/createProcess",desc = "创建流程")
    public JSONObject createProcesController(@RequestBody JSONObject obj){

        //流程模型id
        String processModelId=obj.getString("processModelId");
        //流程标题
        String processTitle=obj.getString("processTitle");
        //流程版本
        String processdefid=obj.getString("processdefid");
        //流程表名
        String tableName=obj.getString("tableName");
        //数据主键id
        String id=obj.getString("id");
        //业务id
        String uuid=UUID.randomUUID().toString();

        Map<String,Object> map=(Map<String,Object>)obj.get("data");
        map.put("id",id);
        map.put("bindid",uuid);
        tableModelService.updateDataById(tableName,map);

        HashMap<String, Object> var = new HashMap<>();
        var.put("uid", 106);
        RuntimeService runtimeService=fLowableUtils.getRuntimeService();

        ProcessInstance processInstance=flowableService.createProcessInstance(processdefid,processTitle,"106",var);


        JSONObject object=new JSONObject();
        object.put("msg","流程创建成功");
        object.put("id",id);
        object.put("processModelId",processModelId);
        object.put("businesskey",uuid);
        object.put("processId",processInstance.getId());
        return Results.success(object);
    }

    @PostMapping(value = "/getformlist",desc = "获取表单列表")
    public JSONObject getFromListController(){
        List<TableModel> tableModelList=tableModelService.getTableModelList();
        JSONArray array=new JSONArray();
        if(tableModelList!=null && tableModelList.size() > 0){
            JSONObject obj=null;
            for (int i = 0; i < tableModelList.size() ; i++) {
                TableModel tableModel=tableModelList.get(i);
                obj=new JSONObject();
                obj.put("id",tableModel.getId()+"");
                obj.put("name",tableModel.getName()+"/"+tableModel.getTableName());
                array.add(obj);
            }
        }
        return Results.success(array);
    }

    @PostMapping(value = "/getcategorys",desc = "获取流程分类")
    public JSONObject getcategoryController(){
        JSONArray array=new JSONArray();
        JSONObject obj1=new JSONObject();
        obj1.put("name","OA项目一");
        obj1.put("id","OA1");
        JSONObject obj2=new JSONObject();
        obj2.put("name","OA项目二");
        obj2.put("id","OA2");
        array.add(obj1);
        array.add(obj2);
        return Results.success(array);
    }

    @PostMapping(value = "/getuerlist",desc = "流程组获取用户列表")
    public JSONObject getUserListController(){
        List<UserModel> userModelList=userModelService.getUserModelList();
        JSONArray array=new JSONArray();
        JSONObject obj1=new JSONObject();
        obj1.put("name","任务创建人");
        obj1.put("id","#{uid}");
        array.add(obj1);
        for (int i = 0; i < userModelList.size() ; i++) {
            UserModel userModel=userModelList.get(i);
            JSONObject obj=new JSONObject();
            obj.put("name",userModel.getRealname()+"/"+userModel.getPhone());
            obj.put("id",userModel.getId());
            array.add(obj);
        }
        return Results.success(array);
    }

    @PostMapping(value = "/getgroup",desc = "获取流程分组")
    public JSONObject getGroupController(){
        JSONArray array=new JSONArray();
        JSONObject obj1=new JSONObject();
        obj1.put("name","候选组一");
        obj1.put("id","OA1");
        JSONObject obj2=new JSONObject();
        obj2.put("name","候选组二");
        obj2.put("id","OA2");
        array.add(obj1);
        array.add(obj2);
        return Results.success(array);
    }

    @PostMapping(value = "/getflowxml",desc = "获取流程")
    public JSONObject getFlowxmlController(@Param("id")String id){
        FlowableModel flowableModel=flowableModelService.getById(id);
        if (flowableModel == null) {
            return Results.error("系统错误");
        }
        JSONObject obj = new JSONObject();
        obj.put("xml",flowableModel.getXml());
        return Results.success(obj);
    }


    @PostMapping(value = "/save",desc = "流程更新或保存")
    public JSONObject saveController(@RequestBody JSONObject obj){
        JSONObject data=(JSONObject)obj.get("data");
        JSONObject process=data.getJSONObject("process");
        String id=process.getString("id");
        String formId="";
        if(!StringUtils.isEmpty(process.get("formLists"))){
            formId=process.getString("formLists");
        }
        String name=process.getString("name");
        String xml=data.getString("xml");
        Object dataId=obj.get("id");
        if(dataId==null){
            FlowableModel flowableModel=new FlowableModel();
            flowableModel.setCreatedate(new Date());
            flowableModel.setProcessdefname(name);
            flowableModel.setName(name);
            flowableModel.setProcessdefid(id);
            flowableModel.setProcessdefkey(id);
            flowableModel.setStatus(false);
            flowableModel.setXml(xml);
            if(!"".equals(formId)){
                flowableModel.setFromId(Integer.parseInt(formId));
            }

            flowableModelService.save(flowableModel);
        }else {
            FlowableModel flowableModel=flowableModelService.getById(dataId);
            if(flowableModel==null){
                return Results.error("系统错误");
            }
            flowableModel.setXml(xml);
            flowableModel.setProcessdefname(name);
            flowableModel.setName(name);
            flowableModel.setProcessdefid(id);
            flowableModel.setProcessdefkey(id);
            flowableModel.setStatus(false);
            flowableModel.setXml(xml);
            if(!"".equals(formId)){
                flowableModel.setFromId(Integer.parseInt(formId));
            }
            flowableModelService.updateById(flowableModel);
        }
        return Results.success("保存成功");
    }

    @PostMapping(value = "/page",desc = "流程分页列表")
    public JSONObject pageController(@Param(value = "pageNum",desc = "页码",defalultValue = "1")Integer pageNum,
                                     @Param(value = "pageSize",desc = "条数",defalultValue = "10")Integer pageSize,
                                     @Param(value = "searchParams",required = false)JSONObject object){
        IPage<FlowableModel> page=flowableModelService.page(pageNum,pageSize,object);
        return Results.successLayuiTable(page);
    }

    @GetMapping(value = "/deploy",desc = "流程部署")
    public JSONObject deployController(@Param("id")String id){
        FlowableModel flowableModel=flowableModelService.getById(id);
        if (flowableModel == null) {
            return Results.error("系统错误");
        }
        RepositoryService repositoryService=fLowableUtils.getRepositoryService();
        Deployment deployStream=repositoryService.createDeployment()
                .name(flowableModel.getProcessdefname())
                .key(flowableModel.getProcessdefkey())
                .addString(flowableModel.getProcessdefname()+".bpmn20.xml", flowableModel.getXml())
                .deploy();

        flowableModel.setProcessdefid(deployStream.getId());
        flowableModel.setStatus(true);
        flowableModelService.updateById(flowableModel);
        return Results.success("部署成功"+deployStream.getId());
    }

    @GetMapping(value = "/getallprocess",desc = "获取所有流程")
    public JSONObject getAllProcessController(){
        RepositoryService repositoryService=fLowableUtils.getRepositoryService();
        List<Deployment> list = repositoryService.createDeploymentQuery().list();
        JSONArray array = new JSONArray();
        for (Deployment deployment : list) {
            JSONObject obj=new JSONObject();
            obj.put("id",deployment.getId());
            obj.put("name",deployment.getName());
            obj.put("key",deployment.getKey());
            array.add(obj);
        }
        return Results.success(array);
    }

    @PostMapping(value = "/getuserdb",desc = "获取用户待办")
    public JSONObject getUserDbController(@Param(value = "pageNum",desc = "页码",defalultValue = "1")Integer pageNum,
                                          @Param(value = "pageSize",desc = "条数",defalultValue = "10")Integer pageSize,
                                          @Param(value = "searchParams",required = false)JSONObject object){
        UserModel userModel=userModelService.getUserModel();
        TaskService taskService=fLowableUtils.getTaskService();
        List<Task> tasks = taskService.createTaskQuery()
                .taskAssignee(String.valueOf(userModel.getId()))
                .orderByTaskCreateTime().desc()
                .listPage(pageNum,pageSize);
        Long count=taskService.createTaskQuery()
                .taskAssignee(String.valueOf(userModel.getId())).count();
        Integer countInteger=Integer.valueOf(String.valueOf(count));
        if(tasks==null || tasks.size() == 0){
            IPage<TaskModel> taskModelIPage=new IPage<TaskModel>(countInteger,Collections.emptyList());
            return Results.successLayuiTable(taskModelIPage);
        }
        List<TaskModel> taskModels=new ArrayList<>();
        RuntimeService runtimeService=fLowableUtils.getRuntimeService();
        if(tasks!=null){
            TaskModel taskModel=null;
            for (Task task : tasks) {
                taskModel=new TaskModel();
                ProcessInstance processInstance=runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
                taskModel.setTaskId(task.getId());
                taskModel.setTaskName(task.getName());
                taskModel.setTitle(processInstance.getName());
                taskModel.setProcessId(processInstance.getId());
                taskModel.setBindID(processInstance.getBusinessKey());
                taskModel.setFromUID(task.getOwner());
                taskModel.setToUID(task.getAssignee());
                taskModels.add(taskModel);
            }
        }
        IPage<TaskModel> taskModelIPage=new IPage<TaskModel>(countInteger,taskModels);
        return Results.successLayuiTable(taskModelIPage);
    }


    @PostMapping(value = "/getuseryb",desc = "获取用户已办")
    public JSONObject getUserYbController(@Param(value = "pageNum",desc = "页码",defalultValue = "1")Integer pageNum,
                                          @Param(value = "pageSize",desc = "条数",defalultValue = "10")Integer pageSize,
                                          @Param(value = "searchParams",required = false)JSONObject object){
        //获取当前登入的用户
        UserModel userModel=userModelService.getUserModel();
        HistoryService historyService=fLowableUtils.getHistoryService();
        List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
                //按结束时间正向排序
                .orderByHistoricTaskInstanceEndTime().asc()
                .taskAssignee(String.valueOf(userModel.getId())).listPage(pageNum,pageSize);
        Long count=historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(String.valueOf(userModel.getId())).count();
        Integer countInteger=Integer.valueOf(String.valueOf(count));
        if(list==null || list.size() == 0){
            IPage<TaskModel> taskModelIPage=new IPage<TaskModel>(countInteger,Collections.emptyList());
            return Results.successLayuiTable(taskModelIPage);
        }
        RuntimeService runtimeService=fLowableUtils.getRuntimeService();
        List<TaskModel> taskModelList=new ArrayList<>();
        for (HistoricTaskInstance historicTaskInstance : list) {
            String processInstanceId=historicTaskInstance.getProcessInstanceId();
            ProcessInstance processInstance=runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
            if(processInstance!=null){
                TaskModel taskModel=new TaskModel();
                taskModel.setTaskId(historicTaskInstance.getId());
                taskModel.setTaskName(historicTaskInstance.getName());
                taskModel.setTitle(processInstance.getName());
                taskModel.setProcessId(processInstance.getId());
                taskModel.setBindID(processInstance.getBusinessKey());
                taskModel.setFromUID(historicTaskInstance.getOwner());
                taskModel.setToUID(historicTaskInstance.getAssignee());
                taskModelList.add(taskModel);
            }else {
                HistoricProcessInstance historicProcessInstance=historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
                TaskModel taskModel=new TaskModel();
                taskModel.setTaskId(historicTaskInstance.getId());
                taskModel.setTaskName(historicTaskInstance.getName());
                taskModel.setTitle(historicProcessInstance.getName());
                taskModel.setProcessId(historicProcessInstance.getId());
                taskModel.setBindID(historicProcessInstance.getBusinessKey());
                taskModel.setFromUID(historicTaskInstance.getOwner());
                taskModel.setToUID(historicTaskInstance.getAssignee());
                taskModelList.add(taskModel);
            }
        }
        IPage<TaskModel> taskModelIPage=new IPage<TaskModel>(countInteger,taskModelList);
        return Results.successLayuiTable(taskModelIPage);
    }


//    @PostMapping(value = "/createProcess",desc = "创建流程")
//    public JSONObject createProcessController(@Param("id")String id,
//                                              @Param("processTitle")String processTitle){
//        FlowableModel flowableModel=flowableModelService.getById(id);
//        if(flowableModel == null){
//            return Results.error("流程不存在");
//        }
//        UserModel userModel=userModelService.getUserModel();
//        System.out.println("流程开始创建了===============>");
//        HashMap<String, Object> map = new HashMap<>();
//        map.put("uid", userModel.getId());
//        RuntimeService runtimeService=fLowableUtils.getRuntimeService();
//        String uuid=UUID.randomUUID().toString();
//        ProcessInstanceBuilder processInstanceBuilder=runtimeService.createProcessInstanceBuilder();
//        processInstanceBuilder.processDefinitionKey(flowableModel.getProcessdefkey());
//        processInstanceBuilder.name(processTitle);
//        processInstanceBuilder.variables(map);
//        processInstanceBuilder.businessKey(uuid);
//        ProcessInstance processInstance=processInstanceBuilder.start();
//
//        JSONObject object=new JSONObject();
//        object.put("msg","流程创建成功");
//        object.put("processId",processInstance.getId());
//        return Results.success(object);
//    }


    @PostMapping(value = "/getallProcessInstancePage",desc = "获取所有正在运行的流程实例")
    public JSONObject getallProcessInstanceController(@Param(value = "pageNum",desc = "页码",defalultValue = "1")Integer pageNum,
                                                      @Param(value = "pageSize",desc = "条数",defalultValue = "10")Integer pageSize,
                                                      @Param(value = "searchParams",required = false)JSONObject object){
        RuntimeService runtimeService=fLowableUtils.getRuntimeService();
        //获取所有正在运行的流程实例
        List<ProcessInstance> processInstanceList=runtimeService.createProcessInstanceQuery().list();
        long count=runtimeService.createActivityInstanceQuery().count();
        Integer countInteger=Integer.valueOf(String.valueOf(count));
        if(processInstanceList==null || processInstanceList.size() == 0){
            IPage<ProcessModel> taskModelIPage=new IPage<ProcessModel>(countInteger,Collections.emptyList());
            return Results.successLayuiTable(taskModelIPage);
        }
        List<ProcessModel> processModelList=new ArrayList<ProcessModel>();
        for (ProcessInstance processInstance : processInstanceList) {
            ProcessModel processModel=new ProcessModel();
            //流程id
            String processId=processInstance.getId();
            //标题名称
            String processName=processInstance.getName();
            //业务key
            String businessKey=processInstance.getBusinessKey();
            //版本id
            String defid=processInstance.getProcessDefinitionId();
            Date startDate=processInstance.getStartTime();
            processModel.setProcessDefId(defid);
            processModel.setTitle(processName);
            processModel.setStartDate(startDate);
            processModel.setProcessId(processId);
            processModel.setBindid(businessKey);
            processModelList.add(processModel);
        }
        IPage<ProcessModel> taskModelIPage=new IPage<ProcessModel>(countInteger,processModelList);
        return Results.successLayuiTable(taskModelIPage);

    }


}
